# dev.setupMiddlewares

- **Type:**

```ts
type SetupMiddlewaresContext = {
  sockWrite: (
    type: string,
    data?: string | boolean | Record<string, any>,
  ) => void;
  environments: EnvironmentAPI;
};

type SetupMiddlewaresFn = (
  middlewares: {
    unshift: (...handlers: RequestHandler[]) => void;
    push: (...handlers: RequestHandler[]) => void;
  },
  context: SetupMiddlewaresContext,
) => void;

type SetupMiddlewares = SetupMiddlewaresFn | SetupMiddlewaresFn[];
```

- **Default:** `undefined`
- **Version:** `>= 1.4.0`

Used to add custom middleware to the dev server.

> See [Dev server - Middleware](/guide/basic/server#middleware) for more information.

## Basic usage

`setupMiddlewares` function receives a `middlewares` array, you can add custom middleware by `unshift` and `push` methods:

- Use `unshift` to prepend middleware to the array, executed earlier than the built-in middleware.
- Use `push` to append middleware to the array, executed later than the built-in middleware.

```ts title="rsbuild.config.ts"
export default {
  dev: {
    setupMiddlewares: (middlewares) => {
      middlewares.unshift((req, res, next) => {
        console.log('first');
        next();
      });

      middlewares.push((req, res, next) => {
        console.log('last');
        next();
      });
    },
  },
};
```

The middleware can be an async function:

```ts title="rsbuild.config.ts"
export default {
  dev: {
    setupMiddlewares: (middlewares) => {
      middlewares.unshift(async (req, res, next) => {
        await someAsyncOperation();
        next();
      });
    },
  },
};
```

`setupMiddlewares` also supports passing an array, each item of which is a function to set up middlewares:

```ts title="rsbuild.config.ts"
export default {
  dev: {
    setupMiddlewares: [
      (middlewares) => {
        // ...
      },
      (middlewares) => {
        // ...
      },
    ],
  },
};
```

:::tip
In versions before Rsbuild 1.4.0, `setupMiddlewares` must pass an array.
:::

## Context object

The second parameter of the `setupMiddlewares` function is the `context` object, which provides some server context and APIs.

### environments

Provides Rsbuild's [environment API](/api/javascript-api/environment-api#environment-api), see [Dev server API - environments](/api/javascript-api/dev-server-api#environments) for more details.

```ts title="rsbuild.config.ts"
export default {
  dev: {
    setupMiddlewares: (middlewares, { environments }) => {
      middlewares.unshift(async (req, _res, next) => {
        const webStats = await environments.web.getStats();
        console.log(webStats.toJson({ all: false }));
        next();
      });
    },
  },
};
```

### sockWrite

Sends some message to HMR client, see [Dev server API - sockWrite](/api/javascript-api/dev-server-api#sockwrite) for more details.

For example, if you send a `'static-changed'` message, the page will reload.

```ts title="rsbuild.config.ts"
export default {
  dev: {
    setupMiddlewares: (middlewares, { sockWrite }) => {
      if (someCondition) {
        sockWrite('static-changed');
      }
    },
  },
};
```
